﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Windows.Forms;
using MessageHandler;

namespace ChatServer
{
	public partial class FormChatServer : Form
	{
		Controller controller;
		public FormChatServer()
		{
			InitializeComponent();
			controller = new Controller(new Configuration() { IpAddress = (Dns.Resolve(IPAddress.Any.ToString())).AddressList[0], Port = 9876 });
			controller.MessageReceived += new Controller.MessageReceivedEventHandler(controller_MessageReceived);
			controller.ErrorOccured += new Controller.ErrorOccuredEventHandler(controller_ErrorOccured);
		}

		#region Events

		private void controller_ErrorOccured(object sender, ErrorOccuredEventArgs e)
		{
			WriteError(e.Error);
		}

		private void controller_MessageReceived(object sender, MessageReceivedEventArgs e)
		{
			WriteMessage(e.Message);
		}

		#endregion

		#region Work

		private delegate void WriteErrorCallback(ChatException chatException);

		private void WriteError(ChatException chatException)
		{
			if (this.InvokeRequired)
			{
				WriteErrorCallback wec = new WriteErrorCallback(WriteError);
				this.Invoke(wec, chatException);
			}
			else
			{
				string[] items = new string[3];
				items[0] = "Error";
				items[1] = chatException.Caption;
				items[2] = chatException.Message;
				ListViewItem itm = new ListViewItem(items);
				lstVwLog.Items.Add(itm);
			}
		}

		private delegate void WriteMessageCallback(MessageHandler.Message message);

		private void WriteMessage(MessageHandler.Message message)
		{
			if (this.InvokeRequired)
			{
				WriteMessageCallback wmc = new WriteMessageCallback(WriteMessage);
				this.Invoke(wmc, message);
			}
			else
			{
				List<UserInfo> userList = new List<UserInfo>();
				switch (message.messageType)
				{
					case MessageType.PRIVATE:
						PrivateMessageType pmType = (PrivateMessageType)message.Item;
						userList.Add(pmType.from);
						userList.AddRange(pmType.to);
						break;
					case MessageType.USERLISTUPDATE:
						UserListUpdateMessageType uluType = (UserListUpdateMessageType)message.Item;
						userList.Add(uluType.currentUser);
						break;
					case MessageType.USERLOGIN:
						UserLoginMessageType ulType = (UserLoginMessageType)message.Item;
						userList.Add(ulType.newUser);
						break;
					case MessageType.USERLOGOUT:
						UserLogoutMessageType uloType = (UserLogoutMessageType)message.Item;
						userList.Add(uloType.loggedOutUser);
						break;
					case MessageType.ERROR:
						//TODO
						break;
					case MessageType.FILETRANSFER:
						FileTransferMessageType ftmType = (FileTransferMessageType)message.Item;
						userList.Add(ftmType.from);
						userList.AddRange(ftmType.to);
						break;
					case MessageType.REGISTER:
						RegisterMessageType rmType = (RegisterMessageType)message.Item;
						userList.Add(rmType.newUser);
						break;
					case MessageType.CONTACTADD:
						ContactAddMessageType caType = (ContactAddMessageType)message.Item;
						userList.Add(caType.fromUser);
						userList.Add(caType.toUser);
						break;
					case MessageType.CONTACTSEARCH:
						break;
					case MessageType.PROFILEUPDATE:
						ProfileUpdateMessageType puType = (ProfileUpdateMessageType)message.Item;
						userList.Add(puType.userInfo);
						break;
					default:
						break;
				}

				AddListViewItem(message.messageType, ToString(userList), message.text);
			}
		}

		private string ToString(List<UserInfo> userList)
		{
			StringBuilder builder = new StringBuilder();
			foreach (UserInfo info in userList)
			{
				builder.Append(info.ToString());
				builder.Append("-");
			}
			return builder.ToString();
		}

		private void AddListViewItem(MessageType type, string userList, string text)
		{
			string[] items = new string[3];
			items[0] = Enum.GetName(typeof(MessageType), type);
			items[1] = userList;
			items[2] = text;
			ListViewItem item = new ListViewItem(items);
			lstVwLog.Items.Add(item);
		}

		private void ChatServer_FormClosing(object sender, FormClosingEventArgs e)
		{
			try
			{
				controller.Close();
			}
			catch (ChatException)
			{
			}
		}
		#endregion

	}
}
